<!--
 * @Description:
 * @version:
 * @Author: 尹鹏孝
 * @Date: 2023-03-17 16:32:42
 * @LastEditors: 尹鹏孝
 * @LastEditTime: 2023-03-21 09:43:06
-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>generator</title>
</head>
<body>
    <script>
        // generator
        function *helloGenerator(){
            yield 'hello';
            yield 'word';
            yield 'ending';
        }

        // var gen = helloGenerator();
        // console.log(gen.next());//{done:false,value:'hello'}
        // console.log(gen.next());//{done:false,value:'word'}
        // console.log(gen.next());//{done:false,value:'ending'}
        // console.log(gen.next());//{done:true,value:undefined}
        // console.log(gen.next());


        function *foo(x){
            var y =(yield (x + 1))*2;
            var z = yield (y / 3);
              console.log(x)
              console.log(y)
              console.log(z)

            return (x + y + z);
        }

        var a = foo(5);
        // console.log(a.next())//6，
        // console.log(a.next(6))//4
        // console.log(a.next(6))//x?,y?,z?
        //  console.log(a.next(6))
        // yield和return
        // 1、yield会暂停并输出结果，结果是false
        // 2、yield会记住之前的数据
        // 3、每一个next都是在执行对应yield
        // 4、最后一个next如果函数有返回则就是最后一个next，value是最后返回的结果，done是true
        // 5、如果没有返回则done是true value是函数默认返回值


        function draw(count){
            console.log(`剩余${count}次`)
            let btn=document.querySelector('#start')
            if(count<=0){
                btn.setAttribute('disabled', true)
                 btn.textContent = '完毕'
            }else{
                 btn.textContent = `剩余${count}次`
            }

        }
        function *remain(count){
            while (count>0) {
                count--
                yield draw(count)
            }
        }

        // let startDraw = remain(6);
        // let btn  = document.createElement('button')
        // btn.id='start'
        // btn.textContent='开始抽奖'
        // document.body.appendChild(btn);
        // document.getElementById('start').addEventListener('click',function(){
        //     startDraw.next();

        // })


        var log = function*(){
            console.log(`you input :${(yield)}`);
        }().next();
        // Object.defineProperty(log,'next',{
        //     value: function*(){
        //         yield
        //     },

        // })
        //console.log(log.next('hello')) ;
        // log.next('hello');

        console.log('-------------')
        function *test(x){
            console.log(x)
            console.log('第一个next开始')
            let m= 1- (yield (x + 3));
            console.log('第二个next在yield前面开始')
            console.log('输出X:',x)
            console.log('输出M:',m)
            var y=2*m;
            console.log(x,y);

            var z = yield(y/4);
             console.log('第三个next在yield前面开始')
            console.log('输出Z:',z)
            console.log(x,y,z);
            // console.log(x,y,z)
            return (x+y+z);
        }

        var gt = test(2);
        console.log(gt.next())
// x:5=>{
//     value:8
// }

        console.log(gt.next(16))
// x:16=>{
//     value:8
// }


        // y:32

        // console.log(gt.next(22))
        // 42 42


        function* gen() {
                yield 123 + 456;
            }
        let psd= gen()
        //直接调用函数不会立即执行需要调用next才能执行
       console.log(gen().next())


       var arr=[1,[1,2],2];
       var flat=function*(a){
        var length = a.length;
        for(var i=0;i<length;i++){
            var item=a[i];
            if(typeof item!=='number'){
                yield* flat(item)
            }else{
                yield
            }
        }
       }

       for(var i of flat(arr)){
        console.log(i)
       }


       var myIterable={};
       myIterable[Symbol.iterator]=function* (){
                yield 1;
                yield 2;
                yield 3;

       };
     // [...myIterable];
    // var myIterable = {};
    //     myIterable[Symbol.iterator] = function* () {
    //         yield 1;
    //         yield 2;
    //         yield 3;
    //     };

       let m =  [...myIterable]
    //...可以遍历一个迭代器generator。generator本身创建就是遍历器生成函数Symbol.iterator
    //调用该函数会返回该对象的一个遍历器对象
    //    generator是遍历器生成函数，
    //
       console.log(m);

       function * mg(){
        for(let i=0;true;i++){
            var reset = yield i;
            if(reset){
                i=-1;
            }
        }
       }
       var g=mg();
      console.log(g.next());
      console.log(g.next());
      console.log(g.next());
      console.log(g.next());
      console.log(g.next());


      function *dataConsumer(){
        console.log('started');
        console.log(`1.${yield}`);
        console.log(`3.${yield}`);
        console.log(`2.${yield}`);
        return 'result';
      }

      let getData = dataConsumer();
    getData.next();
    getData.next('1');
    getData.next('2');
    getData.next('3');
    getData.next('4');
    getData.next('5');



    function wrapper(generatorFunction){
        return function(...arg){
            let generatorObject = generatorFunction(...arg);
            generatorObject.next();
            return generatorObject;
        }
    }

    const wrapped = wrapper(function *(){
        console.log(`First input ${yield}`);
        return 'DONE';
    })

    wrapped().next('hello')
    // function wrapper(generatorFunction) {
    //     return function (...args) {
    //         let generatorObject = generatorFunction(...args);
    //         generatorObject.next();
    //         return generatorObject;
    //     };
    // }

    // const wrapped = wrapper(function* () {
    //     console.log(`First input: ${yield}`);
    //     return 'DONE';
    // });

    // wrapped().next('hello!')
        //for...of遍历generator不需要调用next
        // function *fibonacci(){
        //     let [prev,curr]=[0,1];
        //     for(;;){
        //         yield curr;
        //         [prev,curr]=[curr,prev+curr]
        //     }
        // }

        // for(let n of fibonacci()){
        //     if(n>1000){
        //         break;
        //         console.log(n);
        //     }
        // }


        function *interEntries(obj){
            let keys=Object.keys(obj);
        }

        //generator和异步

    </script>
</body>
</html>